package com.yeziji.utils;

import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Http 请求工具类
 *
 * @author gzkemays
 * @since 2022/1/14 20:39
 */
public class HttpUtils {
    /**
     * 获取有参列表对象
     *
     * @param map 请求数据
     * @return 有参列表对象
     */
    public static List<NameValuePair> getPairListByMap(Map<String, Object> map) {
        List<NameValuePair> list = new ArrayList<>();
        if (!map.isEmpty()) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
            }
        }
        return list;
    }

    /**
     * 获取无参 http get 对象
     *
     * @param url 请求地址
     * @return {@link HttpGet}
     */
    public static HttpGet getHttpGet(String url) {
        return new HttpGet(url);
    }

    /**
     * 获取有参 http get 对象
     *
     * @param url 请求地址
     * @param map 请求参数
     * @return {@link HttpGet}
     */
    public static HttpGet getDataGet(String url, Map<String, Object> map) {
        HttpGet httpGet = getHttpGet(url);
        List<NameValuePair> list = getPairListByMap(map);
        if (!list.isEmpty()) {
            String param = URLEncodedUtils.format(list, "UTF-8");
            httpGet.setURI(URI.create(url + "?" + param));
        }
        return httpGet;
    }

    /**
     * 获取无参 http post 对象
     *
     * @param url 请求地址
     * @return {@link HttpPost}
     */
    public static HttpPost getHttpPost(String url) {
        return new HttpPost(url);
    }

    /**
     * 获取表单请求 post
     *
     * @param url 请求地址
     * @param map 表单对应键值对
     * @return {@link HttpPost}
     */
    public static HttpPost getUrlEncodedFormPost(
            String url, Map<String, Object> map, Charset charset) {
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> list = getPairListByMap(map);
        if (list.size() > 0) {
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, charset);
            httpPost.setEntity(urlEncodedFormEntity);
        }
        return httpPost;
    }

    /**
     * http json post 请求
     *
     * @param url   请求地址
     * @param param json 字符串
     * @return {@link HttpPost}
     */
    public static HttpPost getPostJson(String url, String param) {
        StringEntity entity = new StringEntity(param, "utf-8");
        entity.setContentType("application/json");
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(entity);
        return httpPost;
    }

    /**
     * 获取 cookie
     *
     * <p>将 Cookie name value 以 name=value; 的形式拼接为字符串
     *
     * @param store cooke 存储器
     * @return cookie 字符串
     */
    public static String getCookie(CookieStore store) {
        List<Cookie> cookies = store.getCookies();
        StringBuilder tempcookies = new StringBuilder();
        for (Cookie c : cookies) {
            tempcookies.append(c.getName()).append("=").append(c.getValue()).append(";");
        }
        return tempcookies.toString();
    }

    /**
     * HttpClient 线程池
     */
    public static PoolingHttpClientConnectionManager poolingHttpClient() {
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(50);
        return cm;
    }

    /**
     * 忽略 ssl 证书
     */
    public static CloseableHttpClient getIgnoreSslClient() throws Exception {
        SSLContext sslContext =
                SSLContexts.custom()
                        .loadTrustMaterial(
                                null,
                                new TrustStrategy() {
                                    @Override
                                    public boolean isTrusted(X509Certificate[] x509Certificates, String s)
                                            throws CertificateException {
                                        return true;
                                    }
                                })
                        .build();
        // 创建httpClient
        return HttpClients.custom()
                .setSSLContext(sslContext)
                .setSSLHostnameVerifier(new NoopHostnameVerifier())
                .build();
    }
}
